﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using SegIdenMovilBT.Entidad;
using SegIdenMovilBT.DataAccess;
using System.Data;

namespace SegIdenMovilBT.Datos
{
    public class VentaDA
    {
        #region --- Constantes ---
        private const string PARAM_CAB_SERIE =  "@SERIE";
        private const string PARAM_CAB_NUMERO =  "@NUMERO";
        private const string PARAM_CAB_CODCLINTE = "@CODCLIENTE";
        private const string PARAM_CAB_CODTIPODOCUMENTOVENTA = "@CODTIPODOCUMENTOVENTA";
        private const string PARAM_CAB_CODMONEDA = "@CODMONEDA";
        private const string PARAM_CAB_CODFORMAVENTA = "@CODFORMAVENTA";
        private const string PARAM_CAB_TOTAL = "@TOTAL";
        private const string PARAM_CAB_SUBTOTAL = "@SUBTOTAL";
        private const string PARAM_CAB_IGV = "@IGV";
        private const string PARAM_CAB_CODUSUARIO = "@CODUSUARIO";
        private const string PARAM_CAB_ESTADO = "@ESTADO";
        private const string PARAM_CAB_CODTIENDA = "@CODTIENDA";
        private const string PARAM_CAB_CODDISENIADOR = "@CODDISENIADOR";
        private const string PARAM_CAB_NUMERONCREDITO = "@NUMERONCREDITO";
        private const string PARAM_CAB_SERIENCREDITO = "@SERIENCREDITO";

        private const string PARAM_DET_CODVENTA = "@CODVENTA";
        private const string PARAM_DET_CODPRODUCTO = "@CODPRODUCTO"; 
        private const string PARAM_DET_PRECIO = "@PRECIO"; 
        private const string PARAM_DET_CANTIDAD = "@CANTIDAD";

        private const string PARAM_DET_ITEM_CODVENTA = "@CODVENTA"; 
        private const string PARAM_DET_ITEM_NROLINEA = "@NROLINEA"; 
        private const string PARAM_DET_ITEM_CODITEM = "@CODITEM";
        #endregion

        #region --- Metodos Propios ---
        public bool registrarVenta(Venta venta)
        {
            int resultado = 0;

            StringBuilder sentenciaCabeceraSQL = null;
            StringBuilder sentenciaDetalleSQL = null;
            StringBuilder sentenciaDetalleItemSQL = null;

            sentenciaCabeceraSQL = new StringBuilder();
            sentenciaCabeceraSQL.Append("INSERT INTO venta (SERIE, NUMERO, CODCLIENTE, CODTIPODOCUMENTOVENTA, CODMONEDA, CODFORMAVENTA, ");
            sentenciaCabeceraSQL.Append("TOTAL, SUBTOTAL, IGV, CODUSUARIO, ESTADO, FECHAREGISTRO, ");
            sentenciaCabeceraSQL.Append("CODTIENDA, CODDISENIADOR, NUMERONCREDITO, SERIENCREDITO) ");
            sentenciaCabeceraSQL.Append("VALUES (@SERIE, @NUMERO, @CODCLIENTE, @CODTIPODOCUMENTOVENTA, @CODMONEDA, @CODFORMAVENTA, ");
            sentenciaCabeceraSQL.Append("@TOTAL, @SUBTOTAL, @IGV, @CODUSUARIO, @ESTADO, SYSDATE(), ");
            sentenciaCabeceraSQL.Append("@CODTIENDA, @CODDISENIADOR, @NUMERONCREDITO, @SERIENCREDITO);");

            sentenciaDetalleSQL = new StringBuilder();
            sentenciaDetalleSQL.Append("INSERT INTO det_venta (CODVENTA, CODPRODUCTO, PRECIO, CANTIDAD) ");
            sentenciaDetalleSQL.Append("VALUES(@CODVENTA, @CODPRODUCTO, @PRECIO, @CANTIDAD);");

            sentenciaDetalleItemSQL = new StringBuilder();
            sentenciaDetalleItemSQL.Append("INSERT INTO det_venta_item (CODVENTA, NROLINEA, CODITEM) ");
            sentenciaDetalleItemSQL.Append("VALUES (@CODVENTA, @NROLINEA, @CODITEM);");

            // Carga de datos obtenido de la BD
            using (Database db = new Database())
            {
                using (IDbTransaction transa = db.iniciarTransaccionSQLite())
                {
                    #region --- Registro Venta ---
                    db.TextoSQL = sentenciaCabeceraSQL.ToString();
                    db.agregarParametro(PARAM_CAB_SERIE, DbType.String, ParameterDirection.Input, venta.serie);
                    db.agregarParametro(PARAM_CAB_NUMERO, DbType.String, ParameterDirection.Input, venta.numero);
                    db.agregarParametro(PARAM_CAB_CODCLINTE, DbType.Int32, ParameterDirection.Input, venta.cliente.codCliente);
                    db.agregarParametro(PARAM_CAB_CODTIPODOCUMENTOVENTA, DbType.Int32, ParameterDirection.Input, venta.tipoDocumentoVenta.codigo);
                    db.agregarParametro(PARAM_CAB_CODMONEDA, DbType.Int32, ParameterDirection.Input, venta.moneda.codigo);
                    db.agregarParametro(PARAM_CAB_CODFORMAVENTA, DbType.Int32, ParameterDirection.Input, venta.formaVenta.codigo);
                    db.agregarParametro(PARAM_CAB_TOTAL, DbType.Decimal, ParameterDirection.Input, venta.total);
                    db.agregarParametro(PARAM_CAB_SUBTOTAL, DbType.Decimal, ParameterDirection.Input, venta.subTotal);
                    db.agregarParametro(PARAM_CAB_IGV, DbType.Decimal, ParameterDirection.Input, venta.igv);
                    db.agregarParametro(PARAM_CAB_CODUSUARIO, DbType.Int32, ParameterDirection.Input, venta.usuario.codUsuario);
                    db.agregarParametro(PARAM_CAB_ESTADO, DbType.String, ParameterDirection.Input, venta.estado);

                    db.agregarParametro(PARAM_CAB_CODTIENDA, DbType.Int32, ParameterDirection.Input, venta.tienda.codigo);
                    db.agregarParametro(PARAM_CAB_CODDISENIADOR, DbType.Int32, ParameterDirection.Input, null);
                    db.agregarParametro(PARAM_CAB_NUMERONCREDITO , DbType.String, ParameterDirection.Input, venta.notaCreditoNumero);
                    db.agregarParametro(PARAM_CAB_SERIENCREDITO, DbType.String, ParameterDirection.Input, venta.notaCreditoSerie);

                    venta.codVenta = db.ejecutarEscalar().ToString(); 
                    #endregion

                    #region --- Registro Detalle Venta ---
                    db.TextoSQL = sentenciaDetalleSQL.ToString();

                    db.agregarParametro(PARAM_DET_CODVENTA, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_PRECIO, DbType.Decimal, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_CANTIDAD, DbType.Int32, ParameterDirection.Input);

                    foreach (LineaVenta lineaVenta in venta.listaLineaVenta.lista)
                    {
                        db.obtenerParametro(PARAM_DET_CODVENTA).Value = venta.codVenta;
                        db.obtenerParametro(PARAM_DET_PRECIO).Value = lineaVenta.precio;
                        db.obtenerParametro(PARAM_DET_CANTIDAD).Value = lineaVenta.cantidad;

                        lineaVenta.numeroLinea = db.ejecutarEscalar().ToString();

                        #region --- Registro Detalle Item Venta ---
                        db.TextoSQL = sentenciaDetalleItemSQL.ToString();

                        db.agregarParametro(PARAM_DET_ITEM_CODVENTA, DbType.Int32, ParameterDirection.Input);
                        db.agregarParametro(PARAM_DET_ITEM_NROLINEA, DbType.Int32, ParameterDirection.Input);
                        db.agregarParametro(PARAM_DET_ITEM_CODITEM, DbType.Int32, ParameterDirection.Input);

                        foreach (LineaVentaItem lineaVentaItem in lineaVenta.listaLineaVentaItem.lista)
                        {
                            db.obtenerParametro(PARAM_DET_ITEM_CODVENTA).Value = venta.codVenta;
                            db.obtenerParametro(PARAM_DET_ITEM_NROLINEA).Value = lineaVenta.numeroLinea;
                            db.obtenerParametro(PARAM_DET_ITEM_CODITEM).Value = lineaVentaItem.item.codItem;

                            resultado += db.ejecutar();
                        }
                        #endregion
                    }
                    #endregion

                    transa.Commit();
                }
            }

            return resultado >0;
        }
        #endregion
    }
}
